<!DOCTYPE html>
<html lang="zh">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<meta name="keywords" content="dromara.org" />
	<meta name="description" content="dromara.org" />
	<!-- 网页标签标题 -->
	<title>dromara(Open source organization)</title>
	<link rel="shortcut icon" href="/website/img/docsite.ico"/>
	<link rel="stylesheet" href="/website/build/documentation.css" />
</head>
<body>
	<div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/website/zh-cn/index.html"><img class="logo" src="/website/img/dromara.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/website/img/system/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a href="/website/zh-cn/index.html" target="_self">首页</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal menu-item-normal-active"><a href="#">文档</a><div class="sub-menu"><ul><li><a href="/website/zh-cn/docs/soul/soul.html" target="_self">Soul</a></li><li><a href="/website/zh-cn/docs/hmily/index.html" target="_self">Hmily</a></li></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/zh-cn/blog/index.html" target="_self">博客</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/zh-cn/community/index.html" target="_self">社区</a><div class="sub-menu"><ul></ul></div></li></ul></div></div></header><section class="content-section"><div class="sidemenu" id="menu"><div class="sidemenu-toggle"><img src="https://img.alicdn.com/tfs/TB1E6apXHGYBuNjy0FoXXciBFXa-200-200.png"/></div><ul><li class="menu-item menu-item-level-1"><span>Soul</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/soul.html" target="_self">soul介绍</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/team.html" target="_self">团队介绍</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/induction.html" target="_self">soul极简入门</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/db.html" target="_self">数据库设计</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/config.html" target="_self">数据配置流程</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/dataSync.html" target="_self">数据同步原理</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/metaData.html" target="_self">元数据概念介绍</a></li><li style="height:684px;overflow:hidden" class="menu-item menu-item-level-2"><span>用户使用文档<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/setup.html" target="_self">搭建soul网关环境</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-http.html" target="_self">http用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-dubbo.html" target="_self">dubbo用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-springcloud.html" target="_self">springCloud用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-sofa.html" target="_self">sofa用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/selector.html" target="_self">选择器规则详解</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-dataSync.html" target="_self">数据同步策略</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-divide.html" target="_self">divide插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-dubbo.html" target="_self">dubbo插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-springcloud.html" target="_self">springcloud插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sofa.html" target="_self">sofa插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-rateLimiter.html" target="_self">rateLimiter插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-hystrix.html" target="_self">hystrix插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-monitor.html" target="_self">monitor插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-waf.html" target="_self">waf插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sign.html" target="_self">sign插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-rewrite.html" target="_self">rewrite插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-websocket.html" target="_self">websocket支持</a></li></ul></li><li style="height:360px;overflow:hidden" class="menu-item menu-item-level-2"><span>开发者文档<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-filter.html" target="_self">自定义filter</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-plugin.html" target="_self">自定义插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-file.html" target="_self">文件上传下载</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-iphost.html" target="_self">自定义解析IP与host</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-result.html" target="_self">自定义返回结果</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-sign.html" target="_self">自定义签名插件算法与验证</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-client.html" target="_self">多语言http客户端接入</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-thread.html" target="_self">线程模型</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-netty.html" target="_self">soul调优</a></li></ul></li><li style="height:144px;overflow:hidden" class="menu-item menu-item-level-2"><span>社区贡献<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/contributor.html" target="_self">贡献者指南</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/committer.html" target="_self">提交者指南</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/code-conduct.html" target="_self">编码规范</a></li></ul></li></ul></li></ul></div><div class="doc-content markdown-body" id="doc-body"><h2>说明</h2>
<ul>
<li>sign插件是 soul网关自带的，用来对请求进行签名认证的插件。</li>
</ul>
<h2>插件设置</h2>
<ul>
<li>在 <code>soul-admin</code> -&gt; 插件管理中 --&gt; <code>sign</code>插件设置为开启。</li>
</ul>
<h2>插件使用</h2>
<ul>
<li>在网关的 pom.xml 文件中添加 <code>sign</code> 的支持。</li>
</ul>
<pre><code class="language-xml">  <span class="hljs-comment">&lt;!-- soul sign plugin start--&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-plugin-sign<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- soul sign plugin end--&gt;</span>
</code></pre>
<ul>
<li>
<p>选择器和规则，请详细看 : <a href="selector.md">选择器规则</a>。</p>
<ul>
<li>只有匹配的请求，才会进行签名认证。</li>
</ul>
</li>
</ul>
<h2>新增 AK/SK</h2>
<ul>
<li>在soul-admin --&gt; 认证管理中，点击新增，新增一条 AK/SK。</li>
</ul>
<h2>网关技术实现</h2>
<ul>
<li>采用Ak/SK鉴权技术方案。</li>
<li>采用鉴权插件，责任链的模式的模式来完成。</li>
<li>当鉴权插件开启，并配置所有接口鉴权时候生效。</li>
</ul>
<h2>鉴权使用指南</h2>
<ul>
<li>
<p>第一步：AK/SK由网关来进行分配. 比如分配给你的AK为: <code>1TEST123456781</code>  	SK为：<code>506EEB535CF740D7A755CB4B9F4A1536</code></p>
</li>
<li>
<p>第二步：确定好你要访问的网关路径 比如 <code>/api/service/abc</code></p>
</li>
<li>
<p>第三步:构造参数（以下是通用参数）</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>字段</th>
<th style="text-align:right">值</th>
<th style="text-align:center">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>timestamp</td>
<td style="text-align:right">当前时间戳(String类型)</td>
<td style="text-align:center">当前时间的毫秒数（网关会过滤掉5分钟之前的请求）</td>
</tr>
<tr>
<td>path</td>
<td style="text-align:right">/api/service/abc</td>
<td style="text-align:center">就是你需要访问的接口路径(根据你访问网关接口自己变更)</td>
</tr>
<tr>
<td>version</td>
<td style="text-align:right">1.0.0</td>
<td style="text-align:center">目前定位1.0.0 写死，String类型</td>
</tr>
</tbody>
</table>
<p>对上述2个字段进行key的自然排序，然后进行字段与字段值拼接最后再拼接上SK,代码示例。</p>
<p>第一步:首先构造一个Map。</p>
<pre><code class="language-java">
   Map&lt;String, String&gt; map = Maps.newHashMapWithExpectedSize(<span class="hljs-number">2</span>);
   <span class="hljs-comment">//timestamp为毫秒数的字符串形式 String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli()) </span>
   map.put(<span class="hljs-string">"timestamp"</span>,<span class="hljs-string">"1571711067186"</span>);  <span class="hljs-comment">//值应该为毫秒数的字符串形式 </span>
   map.put(<span class="hljs-string">"path"</span>, <span class="hljs-string">"/api/service/abc"</span>);
   map.put(<span class="hljs-string">"version"</span>, <span class="hljs-string">"1.0.0"</span>);
</code></pre>
<p>第二步:进行Key的自然排序，然后Key，Value值拼接最后再拼接分配给你的Sk。</p>
<pre><code class="language-java">List&lt;String&gt; storedKeys = Arrays.stream(map.keySet()
                .toArray(<span class="hljs-keyword">new</span> String[]{}))
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.toList());
<span class="hljs-keyword">final</span> String sign = storedKeys.stream()
                .map(key -&gt; String.join(<span class="hljs-string">""</span>, key, params.get(key)))
                .collect(Collectors.joining()).trim()
                .concat(<span class="hljs-string">"506EEB535CF740D7A755CB4B9F4A1536"</span>);
</code></pre>
<ul>
<li>你得到的sign值应该为:path/api/service/abctimestamp1571711067186version1.0.0506EEB535CF740D7A755CB4B9F4A1536</li>
</ul>
<p>第三步:进行Md5加密后转成大写。</p>
<pre><code class="language-java">DigestUtils.md5DigestAsHex(sign.getBytes()).toUpperCase()
</code></pre>
<ul>
<li>最后得到的值为:A021BF82BE342668B78CD9ADE593D683</li>
</ul>
<h2>请求网关</h2>
<ul>
<li>
<p>假如你访问的路径为 :/api/service/abc。</p>
</li>
<li>
<p>访问地址 ：http:网关的域名/api/service/abc。</p>
</li>
<li>
<p>设置<code>header</code>头，<code>header</code>头参数为：</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>字段</th>
<th style="text-align:right">值</th>
<th style="text-align:center">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>timestamp</td>
<td style="text-align:right"><code>1571711067186</code></td>
<td style="text-align:center">上述你进行签名的时候使用的时间值</td>
</tr>
<tr>
<td>appKey</td>
<td style="text-align:right"><code>1TEST123456781</code></td>
<td style="text-align:center">分配给你的Ak值</td>
</tr>
<tr>
<td>sign</td>
<td style="text-align:right"><code>A90E66763793BDBC817CF3B52AAAC041</code></td>
<td style="text-align:center">上述得到的签名值</td>
</tr>
<tr>
<td>version</td>
<td style="text-align:right"><code>1.0.0</code></td>
<td style="text-align:center">写死，就为这个值</td>
</tr>
</tbody>
</table>
<ul>
<li>签名插件会默认过滤5分钟之后的请求</li>
</ul>
<h2>如果认证不通过会返回 code 为401 message可能会有变动。</h2>
<pre><code class="language-json">"code":401,"message":"sign is not pass,Please check you sign algorithm!","data":null}
</code></pre>
<h2>签名认证算法扩展</h2>
<ul>
<li>请参考开发者文档中的 <a href="dev-sign.md">扩展签名算法</a>。</li>
</ul>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/website/img/dromara.png"/><div class="cols-container"><div class="col col-12"><h3>免责声明</h3><p>任何单位或个人转载本网站的所有相关信息，请注明来源。</p></div><div class="col col-6"><dl><dt>文档</dt><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">概览</a></dd><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">快速开始</a></dd><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">开发者指南</a></dd></dl></div><div class="col col-6"><dl><dt>资源</dt><dd><a href="/website/zh-cn/blog/index.html" target="_self">博客</a></dd><dd><a href="/website/zh-cn/community/index.html" target="_self">社区</a></dd></dl></div></div><div class="copyright"><span>Copyright ©2020 xiaoyu@apache.org by xiaoyu</span></div></div></footer></div></div>
	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
	<script>
		window.rootPath = '/website';
  </script>
	<script src="/website/build/documentation.js"></script>
</body>
</html>